{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "68e2da59",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from scipy import stats"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b090f350",
   "metadata": {},
   "source": [
    "# Домашнее задание 11\n",
    "\n",
    "Решение задач с проверкой гипотез\n",
    "\n",
    "## 1 Реализация вспомогательных функций"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "846e9705",
   "metadata": {},
   "outputs": [],
   "source": [
    "def equality_probabilities_success(n11, n12, n21, n22):\n",
    "    \"\"\" Рассчет статистики для гипотезы о равенстве вероятности успеха\n",
    "    \n",
    "    Параметры\n",
    "    ---------\n",
    "    n11 : int\n",
    "      Общее количество \"успехов\" в выборке 1\n",
    "    n12 : int\n",
    "      Общее количество \"неудач\" в выборке 1\n",
    "    n21 : int\n",
    "      Общее количество \"успехов\" в выборке 2\n",
    "    n22 : int\n",
    "      Общее количество \"неудач\" в выборке 2\n",
    "    \"\"\"\n",
    "    \n",
    "    # Общее кол-во элементов в первой выборке\n",
    "    n1dot = n11 + n12\n",
    "    # Общее кол-во элементов во второй выборке\n",
    "    n2dot = n21 + n22\n",
    "    \n",
    "    # Общее кол-во людей в обоих выборках\n",
    "    n = n1dot + n2dot\n",
    "    \n",
    "    # Общее кол-во \"успехов\"\n",
    "    ndot1 = n11 + n21\n",
    "    \n",
    "    m1 = n11 / n1dot\n",
    "    m2 = n21 / n2dot\n",
    "    \n",
    "    v = ndot1 / n\n",
    "    \n",
    "    return (m1 - m2) / np.sqrt(v * (1 - v) * (1/n1dot + 1/n2dot))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "5405e793",
   "metadata": {},
   "outputs": [],
   "source": [
    "def u_test(x_array, y_array):\n",
    "    \"\"\"Тест Манна-Уитни-Вилкоксона для несвязанных выборок\n",
    "    \n",
    "    Тест исходит из следующих предположений:\n",
    "      - Если среднее значение y_array больше среднего x_array,\n",
    "      то тетта больше 0.\n",
    "      - Если среднее значение y_array меньше среднего x_array,\n",
    "      то тетта меньше 0.\n",
    "      - Иначе тетта равна 0.\n",
    "      \n",
    "    Из этих предположений необходимо корректно сформировать гипотезу.\n",
    "    \n",
    "    Параметры\n",
    "    ---------\n",
    "    x_array : np.ndarray\n",
    "      Массив значений выборки X\n",
    "    y_array : np.ndarray\n",
    "      Массив значений выборки Y\n",
    "      \n",
    "    Результат\n",
    "    ---------\n",
    "    u_test_statistic : float\n",
    "    \"\"\"\n",
    "    \n",
    "    if not isinstance(x_array, np.ndarray):\n",
    "        x_array = np.array(x_array)\n",
    "        x_array = y_array.flatten()\n",
    "        \n",
    "    if not isinstance(y_array, np.ndarray):\n",
    "        y_array = np.array(y_array)\n",
    "        y_array = y_array.flatten()\n",
    "        \n",
    "    assert len(x_array.shape) == 1  and len(y_array.shape) == 1\n",
    "        \n",
    "    arr_concat = np.hstack([x_array, y_array])\n",
    "    y_array_start_stack_index = len(x_array)\n",
    "    \n",
    "    sorted_index_arr_concat = np.argsort(arr_concat)\n",
    "    \n",
    "    ranked_arr_concat = stats.rankdata(arr_concat[sorted_index_arr_concat])\n",
    "    \n",
    "    y_array_ranks = stats.rankdata(np.where(sorted_index_arr_concat >= y_array_start_stack_index)[0])\n",
    "    \n",
    "    len_x_array = len(x_array)\n",
    "    len_y_array = len(y_array)\n",
    "    \n",
    "    \n",
    "    W = np.sum(y_array_ranks)\n",
    "    M = len_y_array * (len_x_array + len_y_array + 1) / 2\n",
    "    D = len_y_array * len_x_array * (len_x_array + len_y_array + 1) / 12\n",
    "    \n",
    "    return (W - M) / np.sqrt(D)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e21a1301",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_p_value(stat_value, side='both', stat_type='norm'):\n",
    "    \"\"\" Расчет p-value для значения статистики\n",
    "    \n",
    "    Параметры\n",
    "    ---------\n",
    "    stat_value : float\n",
    "      Значение статистики\n",
    "    side : str\n",
    "      Сторона теста для вычисления p-value\n",
    "    stat_type : str\n",
    "      Тип распределения значения статистики.\n",
    "      Поддерживается только значение norm\n",
    "      \n",
    "    Результат\n",
    "    ---------\n",
    "    p_val : float\n",
    "    \"\"\"\n",
    "    \n",
    "    side = str(side).lower().strip()\n",
    "    assert side in ('both', 'left', 'right')\n",
    "    stat_type = str(stat_type).lower().strip()\n",
    "    assert stat_type in ('norm')\n",
    "    \n",
    "    if stat_type == 'norm':\n",
    "        z_quantile = stats.norm.cdf(stat_value)\n",
    "    \n",
    "    if side == 'both':\n",
    "        p_val = np.min([2*z_quantile, 2 - 2*z_quantile])\n",
    "    elif side == 'left':\n",
    "        p_val = z_quantile\n",
    "    else:\n",
    "        p_val = 1 - z_quantile\n",
    "        \n",
    "    return p_val"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9d9408a",
   "metadata": {},
   "source": [
    "## 2 Решение задач\n",
    "\n",
    "### Задача 3.1\n",
    "\n",
    "Перед президентскими выборами в городах Курске и Владивостоке был проведен\n",
    "социологический опрос. Каждый респондент должен был ответить на вопрос:\n",
    "«За какого кандидата вы будете голосовать на выборах». В Курске опросили\n",
    "105 человек, из них 42 ответили, что будут голосовать за кандидата А, во\n",
    "Владивостоке опросили 195 человек, из которых 65 за А. Можно ли считать\n",
    "на уровне значимости 0,05, что уровни поддержки кандидата А в Курске и\n",
    "Владивостоке одинаковы?\n",
    "\n",
    "**Решение:**\n",
    "\n",
    "Сформулируем гипотезы:\n",
    "\n",
    "H0: p0 = p1\n",
    "\n",
    "H1: p0 != p1\n",
    "\n",
    "Здесь p1 - вероятность победы кандидата А в Курске, а p2 - вероятность победы кандидата А во Владивостоке.\n",
    "\n",
    "Для проверки гипотезы будет использовать статистику гипотезы о равенстве вероятностей успеха. Так как нас интересует отклонение уровня поддержки в обе стороны, то проверка гипотезы будет двусторонней."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "8af31563",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Значение статистики: 1.14977\n",
      "Значение p-value: 0.25024\n",
      "H0: Поддержка кандидата А одинакова в Самаре и Владивостоке на уровне значимости 0.05\n"
     ]
    }
   ],
   "source": [
    "alpha = 0.05\n",
    "\n",
    "# Количество готовых проголосовать за А в Курске\n",
    "n11 = 42\n",
    "# Количество готовых проголосовать за А во Владивостоке\n",
    "n21 = 65\n",
    "# Отказавшивеся голосовать за А в Курске\n",
    "n12 = 105 - n11\n",
    "# Отказавшивеся голосовать за А во Владивостоке\n",
    "n22 = 195 - n21\n",
    "\n",
    "stat_val = equality_probabilities_success(n11=n11, n12=n12, n21=n21, n22=n22)\n",
    "p_val = get_p_value(stat_val, side='both')\n",
    "\n",
    "print(\"Значение статистики:\", round(stat_val, 5))\n",
    "print(\"Значение p-value:\", round(p_val, 5))\n",
    "\n",
    "if p_val >= alpha:\n",
    "    print(f\"H0: Поддержка кандидата А одинакова в Самаре и Владивостоке на уровне значимости {alpha}\")\n",
    "else:\n",
    "    print(f\"H1: Поддержка кандидата А различна в Самаре и Владивостоке на уровне значимости {alpha}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87043754",
   "metadata": {},
   "source": [
    "###  Задача 3.2\n",
    "\n",
    "Для изучения эффективности лекарства против аллергии обследовались две\n",
    "группы людей, предрасположенных к этому заболеванию. Результаты обследования\n",
    "следующие: среди принимавших лекарство заболело 3 человека, не заболело\n",
    "172 человека; среди не принимавших заболело 32 человека, не заболело 168.\n",
    "Указывают ли эти результаты на эффективность лекарства?\n",
    "\n",
    "**Решение:**\n",
    "\n",
    "Сформулируем гипотезы:\n",
    "\n",
    "H0: p1 = p2\n",
    "\n",
    "H1: p1 < p2\n",
    "\n",
    "Здесь p1 - вероятность заболеть в группе, принимавшей лекарство. А p2 - вероятность заболеть в группе, не принимавшей лекарство.\n",
    "\n",
    "Для проверки гипотезы будем использовать статистику гипотезы о равенстве вероятностей успеха. Нас интересует отклонение только в левую сторону, поэтому проверка гипотезы будет левосторонней."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "dd0a19bd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Значение статистики: -4.74437\n",
      "Значение p-value: 0.0\n",
      "H1: Лекарство эффективно на уровне значимости 0.05\n"
     ]
    }
   ],
   "source": [
    "alpha = 0.05\n",
    "\n",
    "# Количество заболевших группе 1, принимавшей лекарство.\n",
    "n11 = 3\n",
    "# Количество заболевших группе 2, не принимавшей лекарство.\n",
    "n21 = 32\n",
    "# Количество не заболевших группе 1, принимавшей лекарство.\n",
    "n12 = 172\n",
    "# Количество не заболевших группе 2, не принимавшей лекарство.\n",
    "n22 = 168\n",
    "\n",
    "stat_val = equality_probabilities_success(n11=n11, n12=n12, n21=n21, n22=n22)\n",
    "p_val = get_p_value(stat_val, side='left')\n",
    "\n",
    "print(\"Значение статистики:\", round(stat_val, 5))\n",
    "print(\"Значение p-value:\", round(p_val, 5))\n",
    "\n",
    "if p_val >= alpha:\n",
    "    print(f\"H0: Лекарство не эффективно на уровне значимости {alpha}\")\n",
    "else:\n",
    "    print(f\"H1: Лекарство эффективно на уровне значимости {alpha}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e09ca58e",
   "metadata": {},
   "source": [
    "### Задача 3.3\n",
    "\n",
    "Было проведено обследование 10 горожан и 9 жителей села примерно одного\n",
    "возраста. Получены следующие данные об уровне давления:\n",
    "\n",
    "для горожан: 130, 110, 120, 140, 200, 130, 140, 170, 160, 140;\n",
    "\n",
    "для селян: 120, 190, 130, 160, 150, 120, 110, 120, 200.\n",
    "\n",
    "Свидетельствуют ли эти данные в пользу того, что горожане имеют в среднем\n",
    "более высокое давление чем жители сельской местности?\n",
    "\n",
    "**Решение:**\n",
    "\n",
    "Сформулируем гипотезы:\n",
    "\n",
    "H0: X = Y\n",
    "\n",
    "H1: X < Y\n",
    "\n",
    "Здесь X - среднее значение давления селян, a Y - среднее значение давления горожан."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "5ce45dd6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Значение статистики: -3.67423\n",
      "Значение p-value: 0.99988\n",
      "H0: Среднее значение давления горожан не имеет более высокое значение в сравнении с селянами на уровне значимости 0.05\n"
     ]
    }
   ],
   "source": [
    "alpha = 0.05\n",
    "\n",
    "x_array = np.array([130, 110, 120, 140, 200, 130, 140, 170, 160, 140])\n",
    "y_array = np.array([120, 190, 130, 160, 150, 120, 110, 120, 200])\n",
    "\n",
    "stat_val = u_test(x_array=x_array, y_array=y_array)\n",
    "\n",
    "# Так как предполагается, что средние значения Y больше X, то гипотеза будет правосторонней\n",
    "p_val = get_p_value(stat_val, side='right')\n",
    "\n",
    "print(\"Значение статистики:\", round(stat_val, 5))\n",
    "print(\"Значение p-value:\", round(p_val, 5))\n",
    "\n",
    "if p_val >= alpha:\n",
    "    print(\"H0: Среднее значение давления горожан не имеет более высокое значение\" +\n",
    "          f\" в сравнении с селянами на уровне значимости {alpha}\")\n",
    "else:\n",
    "    print(\"H1: Среднее значение давления горожан имеет более высокое значение\" +\n",
    "          f\" в сравнении с селянами на уровне значимости {alpha}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4bc7e399",
   "metadata": {},
   "source": [
    "### Задача 3.4\n",
    "\n",
    "Уровень гистамина в мокроте у 7 курильщиков, склонных к аллергии, составил в мг:\n",
    "\n",
    "102,4 100,0 67,6 65,9 64,7 39,6 31,2\n",
    "\n",
    "У 10 курильщиков, не склонных к аллергии, составил в мг:\n",
    "\n",
    "48,1 45,5 41,7 35,4 29,1 18,9 58,3 68,8 71,3 94,3\n",
    "\n",
    "Можно ли, основываясь на этих данных, считать с надёжностью 0,95 что уровень гистамина у склонных и не склонных к аллергии курильщиков значимо различается?\n",
    "\n",
    "**Решение:**\n",
    "\n",
    "Сформулируем гипотезы:\n",
    "\n",
    "H0: X = Y\n",
    "\n",
    "H1: X != Y\n",
    "\n",
    "Здесь X - уровень гистамина у курильщиков, склонных к алергии, a Y - уровень гистамина у курильщиков, не склонных к алергии"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "3a4a318a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Значение статистики: -3.41565\n",
      "Значение p-value: 0.00064\n",
      "H1: уровень гистамина у склонных и не склонных к аллергии курильщиков различается на уровне значимости 0.05\n"
     ]
    }
   ],
   "source": [
    "alpha = 0.05\n",
    "\n",
    "x_array = np.array([102.4, 100.0, 67.6, 65.9, 64.7, 39.6, 31.2])\n",
    "y_array = np.array([48.1, 45.5, 41.7, 35.4, 29.1, 18.9, 58.3, 68.8, 71.3, 94.3])\n",
    "\n",
    "stat_val = u_test(x_array=x_array, y_array=y_array)\n",
    "\n",
    "# Так как предполагается, что средние значения Y больше X, то гипотеза будет правосторонней\n",
    "p_val = get_p_value(stat_val, side='both')\n",
    "\n",
    "print(\"Значение статистики:\", round(stat_val, 5))\n",
    "print(\"Значение p-value:\", round(p_val, 5))\n",
    "\n",
    "if p_val >= alpha:\n",
    "    print(f\"H0: уровень гистамина у склонных и не склонных к аллергии курильщиков не различается на уровне значимости {alpha}\")\n",
    "else:\n",
    "    print(f\"H1: уровень гистамина у склонных и не склонных к аллергии курильщиков различается на уровне значимости {alpha}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
